import uuid, datetime
from gluon.contrib.markdown import WIKI

QUEUED, PROCESSING, COMPLETED, FAILED = 'queued', 'processing', 'completed','failed'

user_id = auth.user.id if auth.is_logged_in() else 0
auth.user_id = user_id
login = A('login',_href=URL(r=request,f='user/login'))

def Private(*a,**b):
    b['writable']=b['readable']=False
    return Field(*a,**b)

####################################
# table stream
####################################

def url(f,*args): return URL(r=request,c='default',f=f,args=args)

db.define_table('stream',
                Field('name'),
                Field('description','text',default=''),
                Private('posted_by',db.auth_user,default=user_id),
                Private('posted_on','datetime',default=request.now),
                Private('maplot','upload',autodelete=True),
                Private('plplot','upload',autodelete=True),
                format='%(name)')

db.stream.name.requires=[IS_NOT_EMPTY(),IS_NOT_IN_DB(db,'stream.name')]
db.stream.id.represent=lambda id:SPAN(SPAN(id,_class="id0"),' ',A('edit',_href=url('edit_stream',id)),' ',A('select',_href=url('stream',id)))

####################################
# table configufile stores a gauge configuration
####################################

db.define_table('configfile',
                Private('stream',db.stream),
                Field('file','upload',autodelete=False),
                Private('local','boolean',default=False),
                Private('localmdp','boolean',default=False),
                Field('filename',default='auto',writable=False),
                Field('format',default='auto',writable=False),
                Field('lattice_size',default='auto',writable=False),
                Field('endianness',default='auto',writable=False),
                Field('precision',default='auto',writable=False),
                Field('plaquette','double',default=0,writable=False),
                Private('converted_file','upload',writable=False),
                Private('posted_by',db.auth_user,default=user_id),
                Private('posted_on','datetime',default=request.now),
                Field('status',default=QUEUED,writable=False),
                format='%(filename)s'),

db.configfile.id.represent=lambda id:SPAN(SPAN(id,_class="id0"),INPUT(_type='checkbox',_name='delete_%s'%id,_id='delete_%s'%id),' ',A('edit',_href=url('edit_configfile',id)),' ',A('select',_href=url('process',id)))
db.configfile.file.requires=IS_NOT_EMPTY()
db.configfile.status.requires=IS_IN_SET((QUEUED,COMPLETED, FAILED, PROCESSING),zero=None)



####################################
# stores possible processing algorithms
####################################

db.define_table('algorithm',
                Field('name', unique=True),
                Field('description'),
                format='%(name)s')

if db(db.algorithm.name == 'topological_charge').count() == 0:
    db.algorithm.insert(name='topological_charge',
                        description='Topological charge description')
if db(db.algorithm.name == 'polyakov').count() == 0:
    db.algorithm.insert(name='polyakov',
                        description='Polyakov')

####################################
# stores the output (including vtk files) from 
# running the algorithm on a configile
####################################

db.define_table('processedfile',
                Private('configfile',db.configfile),
                Field('status',default=QUEUED,writable=False),
                Field('algorithm'),
                Private('stdin','text'),
                Private('stdout','text'),
                Private('stderr','text'),
                Private('vtkfile','upload',autodelete=True),
                Private('posted_by',db.auth_user,default=user_id),
                Private('posted_on','datetime',default=request.now),
                Private('start_processing_on','datetime',default=request.now),
                Private('completed_processing_on','datetime'),
                format='%(algorithm)s.%(configfile)s')

db.processedfile.id.represent=lambda id:SPAN(SPAN(id,_class="id0"),INPUT(_type='checkbox',_name='delete_%s'%id,_id='delete_%s'%id),' ',A('edit',_href=url('edit_processedfile',id)),' ',A('select',_href=url('visual',id)))
db.processedfile.status.requires=IS_IN_SET((QUEUED,COMPLETED, FAILED, PROCESSING),zero=None)
db.processedfile.algorithm.requires=IS_IN_DB(db,'algorithm.name',zero=None)

#
#  plot types. Why is this here?
#

PLOTTYPE = [
    ('VolumeSplatting'),
    ('Pseudocolor & Isosurface'),
    ('VolumeRayCasting')
]

####################################
# this is the visualization of a VTK file (processedfile)
####################################

db.define_table('visualizedfile',
                Field('name'),
                Field('plott',label="Plot Type"),
                Field('background_color',default='black'),
                Private('processedfile',db.processedfile),
                Field('status',default='queued',writable=False),
                Private('viewangle',default=[session.p3d_alpha,session.p3d_beta]),
                Private('stdin','text'), # do we need this?
                Private('stdout','text'), # do we need this?
                Private('stderr','text'), # do we need this?
                Field('pngfile','upload',autodelete=True,writable=False),
                Private('posted_by',db.auth_user,default=user_id),
                Private('posted_on','datetime',default=request.now),
                Private('start_processing_on','datetime',default=request.now),
                Private('completed_processing_on','datetime'),
                format='%(name)s.%(processedfile)s')

db.visualizedfile.id.represent=lambda id:SPAN(SPAN(id,_class="id0"),INPUT(_type='checkbox',_name='delete_%s'%id,_id='delete_%s'%id),' ',A('edit',_href=url('edit_visualizedfile',id)),' ',A('select',_href=url('show_visual',id)))
db.visualizedfile.name.requires=IS_NOT_EMPTY()
db.visualizedfile.status.requires=IS_IN_SET((QUEUED, COMPLETED, FAILED, PROCESSING),zero=None)
db.visualizedfile.background_color.requires=IS_IN_SET(('black','white'))
db.visualizedfile.processedfile.requires=IS_IN_DB(db,'processedfile.id','%(id)s')
db.visualizedfile.plott.requires=IS_IN_SET(PLOTTYPE,zero=None)
db.visualizedfile.pngfile.represent=lambda name: A(IMG(_src=url('download',name),_width='200px'),_href=url('download',name),_target='image')

#################################### 
# this stores upload tokens
#################################### 

db.define_table('uploadtoken',
                Field('stream',db.stream),
                Field('token'),
                Field('expiration_date','datetime'))

def locate_file(filename):
    return os.path.join(request.folder,'uploads',filename)

###################################
#this record configfiles in a local folder
###################################
db.define_table('localupload',
                Private('stream',db.stream),
                Field('local_folder','list:string',writable=True))
